unit MLPAAddAssay;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
  Dialogs, Buttons, ExtCtrls, Grids, DB, ADODB, DBGrids, DBCtrls, Spin;

type
  TdlgAddAssay = class(TForm)
    CancelBtn: TButton;
    Bevel1: TBevel;
    dbgSamples: TDBGrid;
    Label1: TLabel;
    Label2: TLabel;
    GroupBox1: TGroupBox;
    dbnavSamples: TDBNavigator;
    cbKitId: TComboBox;
    edtSampleInfo: TEdit;
    OKBtn: TButton;
    Label3: TLabel;
    lblAssayCount: TLabel;
    seReplicates: TSpinEdit;
    Label4: TLabel;
    btnImportTxt: TButton;
    OpenDialog: TOpenDialog;
    procedure OKBtnClick(Sender: TObject);
    procedure edtSampleInfoChange(Sender: TObject);
    procedure cbKitIdChange(Sender: TObject);
    procedure edtSampleInfoKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure edtSampleInfoKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnImportTxtClick(Sender: TObject);
    procedure dbgSamplesTitleClick(Column: TColumn);

  private
    { Private declarations }
    FRunid: integer;
    FSampleInfoEdited: boolean;
    FSampleInfoKeyDown : boolean;
    procedure tblSamplesAfterScroll(DataSet: TDataSet);
    procedure SetAssayCountLabel;
  public
    { Public declarations }
    function AddAssay(kitid:string;runid:integer;SampleInfo:string):integer;
  end;

var
  dlgAddAssay: TdlgAddAssay;

implementation

uses MLPAdm;

{$R *.DFM}

{ TdlgAddAssay }

function TdlgAddAssay.AddAssay(kitid: string;runid:integer;SampleInfo:string): integer;
begin
  if kitid <> '' then
  begin
    cbKitID.Items.Clear;
    cbKitId.Items.Add(kitid);
    cbKitId.ItemIndex:=0;
    cbKitId.Enabled:=false;
    FSampleInfoEdited:=true;
    seReplicates.Enabled:=false;
  end
  else begin
    DM.GetKitIDList(cbKitId.Items);
    cbKitId.Enabled:=true;
    FSampleInfoEdited:=false;
    seReplicates.Enabled:=true;
  end;
  seReplicates.Value:=1;
  FRunId:=runid;
  edtSampleInfo.Text:=SampleInfo;
  DM.tblSamples.AfterScroll:=tblSamplesAfterScroll;
  SetAssayCountLabel;
  FSampleInfoKeyDown:=false;
  ShowModal;
  result:=DM.tblAssays.FieldValues['assayid'];
  DM.tblSamples.AfterScroll:=nil;
end;

procedure TdlgAddAssay.OKBtnClick(Sender: TObject);
var
  AssayId:string;
  i:integer;
begin
  if (cbKitId.ItemIndex<0) or (edtSampleInfo.Text='') then
    ShowMessage('Select a kitid and enter SampleInfo for the assay')
  else begin
    If DM.tblSamples.State=dsEdit then
      DM.tblSamples.Post;
    // check if name exists in run
    if seReplicates.Value=1 then
    begin
      if not DM.SampleInfoExists(FRunId,edtSampleInfo.Text) then
      begin
        DM.tblAssays.InsertRecord([nil,DM.tblSamples.FieldValues['sampleid'],FRunid,cbKitId.Items[cbKitId.ItemIndex],
                                   edtSampleInfo.Text,'']);
        if not cbKitId.Enabled then
          ModalResult:=mrOK;
      end
      else
        ShowMessage('SampleInfo '+edtSampleInfo.Text+' already exists in this run, it must be unique');
    end
    else begin
      for i:=1 to seReplicates.Value do
      begin
        AssayId:=edtSampleInfo.Text+Chr(96+i);
        if not DM.SampleInfoExists(FRunId,AssayId) then
        begin
          DM.tblAssays.InsertRecord([nil,DM.tblSamples.FieldValues['sampleid'],FRunid,cbKitId.Items[cbKitId.ItemIndex],
                                     AssayId,'']);
        end
        else
          ShowMessage('SampleInfo '+AssayId+' already exists in this run, it must be unique');
      end;
    end;
  end;
  DM.qryRunAssays.Requery;
  SetAssayCountLabel;
end;

procedure TdlgAddAssay.edtSampleInfoChange(Sender: TObject);
begin
  if FSampleInfoKeyDown then
    FSampleInfoEdited := true;
end;

procedure TdlgAddAssay.cbKitIdChange(Sender: TObject);
begin
  if Not FSampleInfoEdited then
  begin
    edtSampleInfo.Text:=DM.tblSamples.fieldbyname('LabId').AsString+'-'+cbKitId.Text;
  end;
end;

procedure TdlgAddAssay.dbgSamplesTitleClick(Column: TColumn);
{$J+}
 const PreviousColumnIndex : integer = -1;
{$J-}
begin
  if dbgSamples.DataSource.DataSet is TCustomADODataSet then
  with TCustomADODataSet(dbgSamples.DataSource.DataSet) do
  begin
    if (0<=PreviousColumnIndex) and (PreviousColumnIndex<dbgSamples.Columns.Count) then
    begin
      dbgSamples.Columns[PreviousColumnIndex].title.Font.Style :=
      dbgSamples.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
    end;

    Column.title.Font.Style :=
    Column.title.Font.Style + [fsBold];
    PreviousColumnIndex := Column.Index;

    if (Pos(Column.Field.FieldName, string(Sort)) = 1)
    and (Pos(' DESC', string(Sort))= 0) then
      Sort := Column.Field.FieldName + ' DESC'
    else
      Sort := Column.Field.FieldName + ' ASC';
  end;
end;

procedure TdlgAddAssay.tblSamplesAfterScroll(DataSet: TDataSet);
begin
  FSampleInfoEdited := false;
  cbKitIdChange(Self);
end;

procedure TdlgAddAssay.edtSampleInfoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  FSampleInfoKeyDown:=true;
end;

procedure TdlgAddAssay.edtSampleInfoKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  FSampleInfoKeyDown:=false;
end;

procedure TdlgAddAssay.SetAssayCountLabel;
begin
  lblAssayCount.Caption:=IntToStr(DM.AssayCount(FRunId));
end;

procedure TdlgAddAssay.btnImportTxtClick(Sender: TObject);
var
  txtfile: TStringList;
  fields: TStringList;
  row: integer;
  i:integer;
  HeaderFieldN: Integer;
  SampleField : Integer;
  KitField : Integer;
  SampleInfoField : Integer;
  WellField: Integer;
  SkipRecord:boolean;
  WellData : string;
begin
  // Import from tab delimited file with headers.
  // Currently the following fieldnames are supported
  // SampleName  required, should exist in samples table
  // kit         required, should exist in tbl_SALSA_kitdescription
  // SampleInfo  required
  // Well        optional
  if OpenDialog.Execute then
  begin
    txtfile:=TStringList.Create;
    fields:=TStringList.Create;
    try
      txtfile.LoadFromFile(OpenDialog.FileName);
      if txtfile.Count=0 then
      begin
        ShowMessage('File contains no data');
        exit;
      end;
      ExtractStrings([#9],[' '],PChar(UpperCase(txtfile[0])),fields);
      HeaderFieldN:=fields.Count;
      SampleField:=fields.IndexOf('SAMPLENAME');
      KitField:=fields.IndexOf('KIT');
      SampleInfoField:=fields.IndexOf('SAMPLEINFO');
      WellField:=fields.IndexOf('WELL');
      if (HeaderFieldN=1) then
      begin
        ShowMessage('Your file is probably not tab-separated');
        exit;
      end;
      if (SampleField=-1) or (KitField=-1) or (SampleInfoField=-1) then
      begin
        ShowMessage('Fields "Samplename", "kit" and "SampleInfo" are required in the datafile');
        exit;
      end;
      DM.connMLPAexp.BeginTrans;
      for row:=1 to Pred(txtfile.Count) do
      begin
        SkipRecord:=false;
        fields.Clear;
        ExtractStrings([#9],[' '],PChar(txtfile[row]),fields);

        if fields.Count<>HeaderFieldN then
        begin
          if MessageDlg('Line '+IntToStr(row+1)+' does not contain '+IntToSTr(HeaderFieldN)+' fields. Press ignore to skip this line, abort to cancel all import',mtWarning,[mbAbort,mbIgnore],0)=mrAbort then
          begin
            DM.connMLPAexp.RollbackTrans ;
            Exit;
          end
          else
            SkipRecord:=true;
        end;
        for i:=0 to Pred(Fields.count) do
          fields[i]:=Trim(Fields[i]);
        if not SkipRecord  and ((fields[SampleField]='') or (fields[kitField]='') or (fields[SampleInfoField]='')) then
        begin
          if MessageDlg('Line '+IntToStr(row+1)+': All of SampleName, kit and SampleInfo fields should contain data. Press ignore to skip this line, abort to cancel all import',mtWarning,[mbAbort,mbIgnore],0)=mrAbort then
          begin
            DM.connMLPAexp.RollbackTrans;
            Exit;
          end
          else
            SkipRecord:=true;
        end;
        if not SkipRecord and not DM.tblSamples.Locate('LabId',fields[SampleField],[]) then
        begin
          if MessageDlg('Line '+IntToStr(row+1)+' Sample '+fields[SampleField]+' could not be found in the database. Press ignore to skip this line, abort to cancel all import',mtWarning,[mbAbort,mbIgnore],0)=mrAbort then
          begin
            DM.connMLPAexp.RollbackTrans ;
            Exit;
          end
          else begin
            SkipRecord:=true;
          end;
        end;
        if not SkipRecord and (cbKitId.Items.IndexOf(fields[kitField])=-1) then
        begin
          if MessageDlg('Line '+IntToStr(row+1)+' KitId '+fields[kitField]+' could not be found in the database. Press ignore to skip this line, abort to cancel all import',mtWarning,[mbAbort,mbIgnore],0)=mrAbort then
          begin
            DM.connMLPAexp.RollbackTrans;
            Exit;
          end
          else begin
            SkipRecord:=true;
          end;
        end;
        if not SkipRecord and DM.SampleInfoExists(FRunId,Trim(fields[SampleInfoField])) then
        begin
          if MessageDlg('Line '+IntToStr(row+1)+' SampleInfo '+fields[SampleInfoField]+' already defined for this run. Press ignore to skip this line, abort to cancel all import',mtWarning,[mbAbort,mbIgnore],0)=mrAbort then
          begin
            DM.connMLPAexp.RollbackTrans;
            Exit;
          end
          else begin
            SkipRecord:=true;
          end;
        end;
        if not SkipRecord then
        begin
          if WellField>=0 then
            WellData:=fields[WellField]
          else
            WellData:='';
          DM.tblAssays.InsertRecord([nil,DM.tblSamples.FieldValues['sampleid'],FRunId,fields[KitField],
                                     fields[SampleInfoField],WellData]);
        end;
      end;
    finally
      if DM.connMLPAexp.InTransaction then
        DM.connMLPAexp.CommitTrans;
      txtfile.Free;
      fields.Free;
      DM.qryRunAssays.Requery;
      SetAssayCountLabel;
    end;
  end;
end;

end.
